import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;
  
public class FTPUtil {
    private static Logger logger = Logger.getLogger(FTPUtil.class);
//  logger.info("开始读取绝对路径" + downloadFtpPath + "文件!");

    private Properties properties = null;
    private static String ftpHost;//ip
    private static String ftpPassword;//用户名
    private static String ftpUserName;//密码
    private static int ftpPort;//端口
    private static String downloadFtpPath;//下载ftp文件路径
    private static String updateFtpPath;//上传文件至ftp路径
    private static String localPath;//本地路径
    private static String localTempFielPath;//本地临时文件目录
    private static String charsetName;//ftp编码格式
    
    
    
    /**
     * 初始化FTP所需配置
     * @throws IOException
     */
	public FTPUtil() throws IOException {
		 InputStream in = FTPUtil.class.getClassLoader()  
                 .getResourceAsStream("ftp.properties");
         if(in == null) {
             System.out.println("配置文件ftp.properties读取失败");
         }else {
             properties = new Properties();
             properties.load(in);
             ftpUserName = properties.getProperty("ftpUserName");
             ftpPassword = properties.getProperty("ftpPassword");
             ftpHost = properties.getProperty("ftpHost");
             ftpPort = Integer.valueOf(properties.getProperty("ftpPort")).intValue();
             downloadFtpPath = properties.getProperty("downloadFtpPath");
             updateFtpPath = properties.getProperty("updateFtpPath");
             localPath = properties.getProperty("localPath");
             localTempFielPath = properties.getProperty("localTempFielPath");
             charsetName = properties.getProperty("charsetName");
         }
	}
	
	/** 
     * 获取FTPClient对象 
     * @param ftpHost FTP主机服务器 
     * @param ftpPassword FTP 登录密码 
     * @param ftpUserName FTP登录用户名 
     * @param ftpPort FTP端口 默认为21 
     * @return 
     */  
    public static FTPClient getFTPClient() {
        FTPClient ftpClient = null;
        try {
            ftpClient = new FTPClient();
            ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器  
            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器  
            if(!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                System.out.println("未连接到FTP，用户名或密码错误。");
                ftpClient.disconnect();
            }else {
                System.out.println("FTP连接成功。");
            }
        }catch(SocketException e) {
            e.printStackTrace();
            System.out.println("FTP的IP地址可能错误，请正确配置。");
        }catch(IOException e) {
            e.printStackTrace();
            System.out.println("FTP的端口错误,请正确配置。");
        }
        return ftpClient;
    }
    
    /**
     * 服务器的FTP路径下上读取文件 并保持到本地
     * @param ftpFileName 需要读取的ftp端文件名称
     * @return
     * @throws IOException
     */
    public String readConfigFileForFTP(String ftpFileName) throws IOException {
        StringBuffer resultBuffer = new StringBuffer();
        InputStream in = null;
        FTPClient ftpClient = null;
        System.out.println("开始读取绝对路径" + downloadFtpPath + "文件!");
        try {
            ftpClient = FTPUtil.getFTPClient();
            ftpClient.setControlEncoding("UTF-8"); // 中文支持  
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(downloadFtpPath);
            in = ftpClient.retrieveFileStream(ftpFileName);
        }catch(FileNotFoundException e) {
            logger.error("没有找到" + downloadFtpPath + "文件");
            e.printStackTrace();
            return "下载配置文件失败，请联系管理员："+"没有找到" + downloadFtpPath + "文件。";
        }catch(SocketException e) {
            logger.error("连接FTP失败。");
            e.printStackTrace();
        }catch(IOException e) {
            e.printStackTrace();
            logger.error("文件读取错误。");
            e.printStackTrace();
            return "配置文件读取失败，请联系管理员。文件读取错误。";
        }
        if(in != null) {
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String data = null;
            try {
                while((data = br.readLine()) != null) {
                    resultBuffer.append(data + "\n");
                }
            }catch(IOException e) {
                logger.error("文件读取错误。");
                e.printStackTrace();
                return "配置文件读取失败，请联系管理员：文件读取错误。";
            }finally{
                try {
                    ftpClient.disconnect();
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
        }else{
            logger.error("in为空，不能读取。");
            return "配置文件读取失败，请联系管理员：ftp目标文件为空，不能读取。";
        }
        
        return resultBuffer.toString();
    }
    
    /**
     * 本地上传文件到FTP服务器
     * @param fileContent 文件内容
     */
    public void upload(String fileContent,String uploadFileName) {
        FTPClient ftpClient = null;
        System.out.println("开始上传文件到FTP.");
        try {
            ftpClient = FTPUtil.getFTPClient();
            ftpClient.setControlEncoding("UTF-8");
            // 设置PassiveMode传输  
            ftpClient.enterLocalPassiveMode();
            // 设置以二进制流的方式传输  
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            // 对远程目录的处理  
//          String remoteFileName = uploadFileName;
//            String remoteFileName = updateFtpPath;
//            if(updateFtpPath.contains("/")) {
//                remoteFileName = updateFtpPath  
//                        .substring(updateFtpPath.lastIndexOf("/") + 1);
//            }
//          先把文件写在本地。在上传到FTP上最后在删除  
            boolean writeResult = write(uploadFileName, fileContent,localTempFielPath);
            if(writeResult) {
                File f = new File(localTempFielPath + "/" + uploadFileName);
                InputStream in = new FileInputStream(f);
                //上传路径+上传文件名称
                updateFtpPath = updateFtpPath+"/"+uploadFileName;
                boolean uploadResult = ftpClient.storeFile(this.convertFileName(updateFtpPath), in);
                if(uploadResult){
                    System.out.println("上传文件" + uploadFileName + "到FTP成功!");
                }else{
                    System.out.println("上传文件" + uploadFileName + "到FTP失败!");
                }
                in.close();
                f.delete();
            }else {
                System.out.println("写文件失败!");
            }
        }catch(Exception e) {
            e.printStackTrace();
        }finally{
            try {
                ftpClient.disconnect();
            }catch(IOException e) {
                e.printStackTrace();
            }
        }
    }
  
    /**
     * 把字符型文件内容写到本地
     * @param fileName
     * @param fileContext
     * @param filePath
     * @return
     */
    public boolean write(String fileName, String fileContext,String filePath) {
        try {
            System.out.println("开始写配置文件。");
            File localFile = new File(filePath + "/" + fileName);
            if(!localFile.exists()){
            	File fileDir=new File(localFile.getParent());  
                if(!fileDir.exists()){  
                	fileDir.mkdirs();  //创建文件夹  
                }
                if(!localFile.createNewFile()){
                    System.out.println("文件不存在，创建失败!");
                }
            }
            BufferedWriter bw = new BufferedWriter(new FileWriter(localFile, true));
            bw.write(fileContext.replaceAll("\n", "\r\n"));
            bw.flush();
            bw.close();
            return true;
        }catch(Exception e) {
            logger.error("写文件失败！");
            e.printStackTrace();
            return false;
        }
    }
    
    public String convertFileName(String fileName){
    	String newName = "";
    	try {
			newName = new String(fileName.getBytes(charsetName),"iso-8859-1");
		} catch (UnsupportedEncodingException e) {
			newName = fileName;
		}
    	return newName;
    }
    
    public static void main(String[] args) throws IOException{
    	FTPUtil ftp = new FTPUtil();
//    	String result = ftp.readConfigFileForFTP(new String("上传.txt".getBytes(charsetName),"iso-8859-1"));
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    	String title = sdf.format(new Date());
    	
    	String result = ftp.readConfigFileForFTP("20150605104601.txt");
//    	ftp.write("我的文件"+title+".txt", result, localPath);
//    	ftp.upload("我是上传文件的内容，阿拉拉拉"+title,title+".txt");
    }
    
    
}